package com.egg.basic.service.pay.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.egg.basic.entity.pay.PayRecord;
import com.egg.basic.entity.pay.RefundRecord;
import com.egg.basic.enums.pay.TradeStateEnum;
import com.egg.basic.mapper.pay.RefundRecordMapper;
import com.egg.basic.service.pay.factory.IPayFactory;
import com.egg.basic.service.pay.IPayRecordService;
import com.egg.basic.service.pay.IRefundRecordService;
import com.egg.common.core.exception.CustomException;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.mybatis.service.impl.BaseServiceImpl;
import com.egg.common.util.IdGenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * <p>
 * 退款记录 服务实现类
 * </p>
 *
 * @author east
 * @since 2021-11-26
 */
@Slf4j
@Service
public class RefundRecordServiceImpl extends BaseServiceImpl<RefundRecordMapper, RefundRecord> implements IRefundRecordService {


    @Autowired
    private IPayRecordService payRecordService;


    @Override
    public Optional<RefundRecord> findSuccessByPayRecordId(Long payRecordId) {
        if (ObjectUtil.isEmpty(payRecordId)) {
            return Optional.empty();
        }
        LambdaQueryWrapper<RefundRecord> qw = buildLambdaSortQw();
        qw.eq(RefundRecord::getPayRecordId, payRecordId)
                .eq(RefundRecord::getTradeState, TradeStateEnum.SUCCESS.getCode());
        qw.last("LIMIT 1");
        return Optional.ofNullable(getOne(qw));
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public ResponseData<String> add(String businessType, String businessId, String remark) {
        Optional<PayRecord> payRecordOpt = payRecordService.findSuccess(businessType, businessId);
        if (!payRecordOpt.isPresent()) {
            throw new CustomException("未找到支付记录!");
        }
        PayRecord pr = payRecordOpt.get();
        Optional<RefundRecord> existRefundRecord = findSuccessByPayRecordId(pr.getId());
        if (existRefundRecord.isPresent()) {
            throw new CustomException("请勿重复退款!");
        }
        RefundRecord rr = new RefundRecord();
        rr.setId(IdGenUtil.longId());
        rr.setUserId(pr.getUserId());
        rr.setPayRecordId(pr.getId());
        rr.setTradeNo(pr.getTradeNo());
        rr.setAmount(pr.getAmount());
        rr.setRemark(remark);
        IPayFactory payFactory = IPayFactory.findFactory(pr.getPayType());
        ResponseData<String> rd = payFactory.refund(rr);
        if (rd.isSuccess()) {
            //调用成功, 再次修改状态为成功
            pr.setTradeState(TradeStateEnum.REFUND.getCode());
            payRecordService.baseEdit(pr);
            rr.setTradeState(TradeStateEnum.SUCCESS.getCode());
            rr.setBody(rd.getData());
            baseAdd(rr);
            return ResponseData.success(pr.getId().toString());
        } else {
            //退款失败, 保存失败记录, 并且返回错误信息
            rr.setTradeState(TradeStateEnum.FAIL.getCode());
            rr.setFailMessage(rd.getMsg());
            baseSave(rr);
            return ResponseData.error(rd.getMsg());
        }
    }


}
